from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional, Any, Generic, TypeVar
from datetime import datetime
from app.utils.config import settings


# 定义泛型类型变量
DataT = TypeVar("DataT")


class ApiResponse(BaseModel, Generic[DataT]):
    """统一的API响应格式"""

    code: int = Field(200, description="状态码")
    message: str = Field("success", description="响应消息")
    data: Optional[DataT] = Field(None, description="响应数据")


class ErrorResponse(BaseModel):
    """错误响应格式"""

    code: int = Field(400, description="错误码")
    message: str = Field("error", description="错误消息")
    data: Optional[Any] = Field(None, description="错误详情")


class UserBase(BaseModel):
    """用户基础模型"""

    username: str = Field(..., min_length=3, max_length=50)
    email: EmailStr
    full_name: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = Field(None, max_length=20)
    description: Optional[str] = None


class UserCreate(UserBase):
    """创建用户模型"""

    password: str = Field(..., min_length=6, max_length=100)


class UserUpdate(BaseModel):
    """更新用户模型"""

    username: Optional[str] = Field(None, min_length=3, max_length=50)
    email: Optional[EmailStr] = None
    full_name: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = Field(None, max_length=20)
    description: Optional[str] = None
    avatar_url: Optional[str] = None
    is_active: Optional[bool] = None
    is_superuser: Optional[int] = Field(None, ge=0, le=2)


class UserPasswordUpdate(BaseModel):
    """修改密码模型"""

    current_password: str
    new_password: str = Field(..., min_length=6, max_length=100)


class UserInDB(UserBase):
    """数据库中的用户模型"""

    id: int
    is_active: bool
    is_superuser: int
    avatar_url: Optional[str] = None
    created_at: datetime
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


class UserResponse(UserInDB):
    """用户响应模型（不包含敏感信息）"""

    pass


class Token(BaseModel):
    """Token 模型"""

    access_token: str
    refresh_token: str
    token_type: str = "bearer"


class TokenData(BaseModel):
    """Token 数据模型"""

    user_id: Optional[int] = None
    username: Optional[str] = None


class LoginRequest(BaseModel):
    """登录请求模型"""

    username: str
    password: str


# UnitView相关模型
class UnitViewBase(BaseModel):
    """设备视图基础模型"""

    sn_code: str = Field(..., max_length=100, description="SN码")
    top_view: Optional[str] = Field(None, description="上方位")
    bottom_view: Optional[str] = Field(None, description="下方位")
    left_view: Optional[str] = Field(None, description="左方位")
    right_view: Optional[str] = Field(None, description="右方位")


class UnitViewCreate(UnitViewBase):
    """创建设备视图模型"""

    pass


class UnitViewUpdate(BaseModel):
    """更新设备视图模型"""

    sn_code: Optional[str] = Field(None, max_length=100, description="SN码")
    top_view: Optional[str] = Field(None, description="上方位")
    bottom_view: Optional[str] = Field(None, description="下方位")
    left_view: Optional[str] = Field(None, description="左方位")
    right_view: Optional[str] = Field(None, description="右方位")


class UnitViewResponse(UnitViewBase):
    """设备视图响应模型"""

    id: int
    created_at: datetime
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True

    @validator(
        "top_view", "bottom_view", "left_view", "right_view", pre=False, always=True
    )
    def convert_file_path_to_url(cls, v):
        """将文件路径转换为完整的访问URL"""
        if v and not v.startswith("http"):
            # 如果是相对路径，转换为完整URL
            if v.startswith("uploads/"):
                return f"{settings.BASE_URL}/{v}"
            else:
                return f"{settings.BASE_URL}/uploads/{v}"
        return v
